package com.linkgie.galaxyframework.httpproxy.core;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;

import org.apache.http.Header;
import org.apache.http.HeaderIterator;
import org.apache.http.client.methods.CloseableHttpResponse;

import com.linkgie.galaxyframework.httpproxy.NameValues;
import com.linkgie.galaxyframework.httpproxy.ServiceResponse;
import com.linkgie.galaxyframework.utils.DecodingPipe;

public class ServiceHttpResponse implements ServiceResponse, Closeable {

    private CloseableHttpResponse httpResponse;

    private ResponseHeaders headers = new ResponseHeaders();

    private DecodingPipe responseDecoder;

    private InputStream responseStream;

    public ServiceHttpResponse(CloseableHttpResponse response, DecodingPipe responseDecoder) {
        this.httpResponse = response;
        this.responseDecoder = responseDecoder;
    }

    @Override
    public int getHttpStatusCode() {
        return httpResponse.getStatusLine().getStatusCode();
    }


    @Override
    public String getHttpStatusMessage() {
        return httpResponse.getStatusLine().getReasonPhrase();
    }

    @Override
    public NameValues getHttpHeaders() {
        return headers;
    }

    @Override
    public InputStream getInputStream() throws UnsupportedOperationException, IOException {
        // 重复调用时，返回同一个流；
        if (this.responseStream == null) {
            this.responseStream = initResponseStream();
        }
        return this.responseStream;
    }

    private InputStream initResponseStream() throws IOException {
        InputStream responseStream = httpResponse.getEntity().getContent();
        // 对响应数据进行解码；
        if (responseDecoder != null) {
            responseStream = responseDecoder.decode(responseStream);
        }
        return responseStream;
    }

    @Override
    public void close() throws IOException {
        httpResponse.close();
    }

    private class ResponseHeaders implements NameValues {

        private Set<String> names;

        @Override
        public Set<String> getNames() {
            if (this.names == null) {
                HeaderIterator headerIterator = httpResponse.headerIterator();
                Set<String> names = new LinkedHashSet<>();
                while (headerIterator.hasNext()) {
                    names.add(headerIterator.nextHeader().getName());
                }
                this.names = Collections.unmodifiableSet(names);
            }
            return this.names;
        }

        @Override
        public String getValue(String name) {
            Header header = httpResponse.getFirstHeader(name);
            if (header == null) {
                return null;
            }
            return header.getValue();
        }

    }

}
